package de.rs.espresso.tools.gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JPanel;

import de.rs.espresso.tools.gui.model.Field;
import de.rs.espresso.tools.gui.model.KVModel;

public class KVDrawPanel extends JPanel {

	private static final Color[] COLOR = { new Color(255, 0, 0),
			new Color(0, 255, 0), new Color(0, 0, 255), new Color(255, 255, 0),
			new Color(127, 255, 255), new Color(127, 0, 255),
			new Color(255, 127, 0),new Color(255, 255, 255),new Color(60, 60, 60) };

	private KVModel model;

	public KVDrawPanel(KVModel model) {
		this.model = model;
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		drawDiagramm(g);

		Graphics2D g2 = (Graphics2D) g;
		g2.setStroke(new BasicStroke(3));

		for (int c = 0; c < model.getCubeCount(); c++) {

			g.setColor(COLOR[c]);

			for (Field f : model.getFields()) {

				if (f.contains(c)) {

					drawField(f,c,g);
					

				}

			}

		}

	}

	private void drawDiagramm(Graphics g) {
		g.setColor(new Color(0, 0, 0));

		Font font = new Font("Times New Roman", Font.BOLD, 30);
		g.setFont(font);
		
		g.drawString("KV-Diagram - "+model.getTitle(), 10, 30);
		
		for(Field f : model.getFields()) {
			drawDiagramField(f.x, f.y, g);
		}

		g.drawLine(90, 100, 90, 300);
		g.drawString("A", 50, 210);

		g.drawLine(100, 90, 300, 90);
		g.drawString("B", 195, 70);

		g.drawLine(510, 200, 510, 400);
		g.drawString("C", 520, 310);

		g.drawLine(200, 510, 400, 510);
		g.drawString("D", 290, 550);
	}
	
	private void drawDiagramField(int offSetX, int offSetY, Graphics g) {
		g.drawRect((offSetX+1)*100, (offSetY+1)*100, 100, 100);
	}

	private int deriveInnerX1(Field f, int c) {
		return 100 + f.x * 100 + (c + 1) * 2;

	}

	private int deriveInnerY1(Field f, int c) {
		return 100 + f.y * 100 + (c + 1) * 2;
	}

	private int deriveInnerX2(Field f, int c) {
		return 200 + f.x * 100 - (c + 1) * 2;

	}

	private int deriveInnerY2(Field f, int c) {
		return 200 + f.y * 100 - (c + 1) * 2;
	}

	
	private void drawField(Field f, int c, Graphics g) {
		for (int i = 0; i < 4; i++) {
			drawEdge(f,c,i,g);


		}
	}

	private void drawEdge(Field f, int c, int i, Graphics g) {
		int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
		int xx1 = 0, xx2 = 0, yy1 = 0, yy2 = 0;

		boolean contained = model.getContainedNeighbor(f, c, i);

		if (contained) {
			switch (i) {
			case 0:
				x1 = deriveInnerX1(f, c);
				y1 = deriveInnerY1(f, c);
				x2 = deriveInnerX2(f, c);
				y2 = deriveInnerY1(f, c);
				xx2 = deriveInnerX2(f, c);
				xx1 = deriveInnerX1(f, c);
				yy1 = (f.y + 1) * 100;
				yy2 = (f.y + 1) * 100;
				if (!model.getContainedNeighbor(f, c, 3))
					g.drawLine(x1, y1, xx1, yy1);
				if (!model.getContainedNeighbor(f, c, 1))
					g.drawLine(x2, y2, xx2, yy2);
				break;
			case 1:
				x1 = deriveInnerX2(f, c);
				y1 = deriveInnerY1(f, c);
				x2 = deriveInnerX2(f, c);
				y2 = deriveInnerY2(f, c);
				xx2 = (f.x + 2) * 100;
				xx1 = (f.x + 2) * 100;
				yy1 = deriveInnerY1(f, c);
				yy2 = deriveInnerY2(f, c);
				if (!model.getContainedNeighbor(f, c, 0))
					g.drawLine(x1, y1, xx1, yy1);
				if (!model.getContainedNeighbor(f, c, 2))
					g.drawLine(x2, y2, xx2, yy2);
				break;
			case 2:
				x1 = deriveInnerX2(f, c);
				y1 = deriveInnerY2(f, c);
				x2 = deriveInnerX1(f, c);
				y2 = deriveInnerY2(f, c);
				yy1 = (f.y + 2) * 100;
				yy2 = (f.y + 2) * 100;
				xx1 = deriveInnerX2(f, c);
				xx2 = deriveInnerX1(f, c);
				if (!model.getContainedNeighbor(f, c, 1))
					g.drawLine(x1, y1, xx1, yy1);
				if (!model.getContainedNeighbor(f, c, 3))
					g.drawLine(x2, y2, xx2, yy2);
				break;
			case 3:
				x1 = deriveInnerX1(f, c);
				y1 = deriveInnerY2(f, c);
				x2 = deriveInnerX1(f, c);
				y2 = deriveInnerY1(f, c);
				xx1 = (f.x + 1) * 100;
				xx2 = (f.x + 1) * 100;
				yy2 = deriveInnerY1(f, c);
				yy1 = deriveInnerY2(f, c);
				if (!model.getContainedNeighbor(f, c, 2))
					g.drawLine(x1, y1, xx1, yy1);
				if (!model.getContainedNeighbor(f, c, 0))
					g.drawLine(x2, y2, xx2, yy2);
				break;

			}

		} else {
			switch (i) {
			case 0:
				x1 = deriveInnerX1(f, c);
				y1 = deriveInnerY1(f, c);
				x2 = deriveInnerX2(f, c);
				y2 = deriveInnerY1(f, c);
				break;
			case 1:
				x1 = deriveInnerX2(f, c);
				y1 = deriveInnerY1(f, c);
				x2 = deriveInnerX2(f, c);
				y2 = deriveInnerY2(f, c);
				break;
			case 2:
				x1 = deriveInnerX2(f, c);
				y1 = deriveInnerY2(f, c);
				x2 = deriveInnerX1(f, c);
				y2 = deriveInnerY2(f, c);
				break;
			case 3:
				x1 = deriveInnerX1(f, c);
				y1 = deriveInnerY2(f, c);
				x2 = deriveInnerX1(f, c);
				y2 = deriveInnerY1(f, c);
				break;

			}
			g.drawLine(x1, y1, x2, y2);
		}

		
	}
}
